package voa;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import util.FileOperate;
import voa.Util.LrcFilter;

public class LrcFiles {

	public static class Type {

		public static final Type SPECIAL = new Type("Special");

		public static final Type STAND = new Type("Stand");

		private String name;

		public Type(String name) {
			this.name = name;
		}

		public final boolean equals(Object obj) {
			if (toString() == null) {
				return (obj != null) && (obj.toString() == null);
			}
			if (obj instanceof Type) {
				return toString().equals(obj.toString());
			}
			return false;
		}

		public final int hashCode() {
			if (toString() == null) {
				return 0;
			}
			return toString().hashCode();
		}

		public final String toString() {
			return name;
		}

	}
	
	static private Map lrcFilesMap = new HashMap();
	static private String currentPath = null;

	private Type type;

	private String path;

	private String date;

	private List fileList = new ArrayList();

	private List tmpFiles = new ArrayList();

	public List getTmpFiles() {
		return tmpFiles;
	}

	public void setTmpFiles(List tmpFiles) {
		this.tmpFiles = tmpFiles;
	}

    LrcFiles(String path) {

		setPath(path);

	}
    
    static public LrcFiles instance(String path){
    	
    	LrcFiles lrcFiles = (LrcFiles)lrcFilesMap.get(path);
    	
    	if(null != lrcFiles){
    		
    		return lrcFiles;	
    		
    	} else {
    		
    		lrcFiles = new LrcFiles(path);
    		
    		lrcFilesMap.put(path, lrcFiles);
    		
    		currentPath = path;
    		
    		return lrcFiles;
    		
    	}
    }
    
    static public LrcFiles current(){
    	
    	if(null == currentPath || "".equals(currentPath)){
    		
    		return null;
    	}
    	
    	return (LrcFiles)lrcFilesMap.get(currentPath);
    }

	public Type getType() {
		return type;
	}

	public void setType(Type type) {
		this.type = type;
	}

	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}

	public List getFileList() {
		return fileList;
	}

	public String getPath() {
		return path;
	}

	// 从歌词文件夹名称构建 歌词文件列表对象
	private void setPath(String path) {

		// 目录名称示例
		// VOA常速英语2011年10月
		// VOA慢速英语2011年9月

		File dir = new File(path);

		if (dir.isDirectory()) {

			this.path = path;

			String fileName = dir.getName();

			if (fileName.contains("常速")) {
				
				setType(LrcFiles.Type.STAND);
				
			} else {
				
				setType(LrcFiles.Type.SPECIAL);
			}

			String[] strs = fileName.split("语");

			if (2 == strs.length) {

				String year = strs[1].substring(0, 4);
				String month = strs[1].substring(5, 7);
				if (month.endsWith("月")) {
					month = "0" + month.substring(0, 1);
				}

				setDate(year + "-" + month);
				
			} else {
				
				setDate("2011-01");
				
			}

			File[] files = new File(path).listFiles(new LrcFilter());

			List fileList = new ArrayList();

			for (File file : files) {
				fileList.add(file);
			}

			Collections.sort(fileList);

			this.fileList = fileList;

		}
	}

	private void genOPF() {

		String fileName = getType() + "VOA" + getDate() + ".opf";

		File file = new File(path + "/" + fileName);

		tmpFiles.add(file);

		try {

			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(file), "utf-8"));

			String begin = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "\n";
			begin += "<package xmlns=\"http://www.idpf.org/2007/opf\" version=\"2.0\" unique-identifier=\"BookId\">	"
					+ "\n";
			begin += "<metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:opf=\"http://www.idpf.org/2007/opf\">"
					+ "\n";
			begin += "<dc:title>VOA " + getType() + " English " + getDate()
					+ "</dc:title>" + "\n";
			begin += "<dc:language>en-us</dc:language>" + "\n";
			begin += "<dc:creator>gust</dc:creator>" + "\n";
			begin += "<dc:description>VOA English from www.jiyibao.com</dc:description>"
					+ "\n";
			begin += "</metadata>" + "\n";
			begin += "<manifest>" + "\n";

			String end = "</spine>" + "\n";
			end += "<guide>" + "\n";
			end += "<reference type=\"toc\" title=\"Table of Contents\" href=\"toc.html\"></reference>"
					+ "\n";
			end += "</guide>" + "\n";
			end += "</package>";

			writer.write(begin);

			for (int i = 0; i < fileList.size(); i++) {
				
				String itName = getConversionFileName((File) fileList.get(i));

				String item = "<item id=\"item" + i
						+ "\" media-type=\"application/xhtml+xml\" href=\""
						+ itName + "\"></item>"
						+ "\n";

				writer.write(item);
			}

			String toc = "<item id=\"item"
					+ fileList.size()
					+ "\" media-type=\"application/xhtml+xml\" href=\"toc.html\"></item>"
					+ "\n";
			writer.write(toc);

			String ncx = "<item id=\"My_Table_of_Contents\" media-type=\"application/x-dtbncx+xml\" href=\"voa.ncx\"/>"
					+ "\n";
			writer.write(ncx);

			writer.write("</manifest>" + "\n");
			writer.write("<spine toc=\"My_Table_of_Contents\">" + "\n");

			writer.write("<itemref idref=\"item" + fileList.size() + "\"/>"
					+ "\n");

			for (int i = 0; i < fileList.size(); i++) {

				String item = "<itemref idref=\"item" + i + "\"/>" + "\n";
				writer.write(item);
			}

			writer.write(end);

			writer.close();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	
	private String getConversionFileName(File file){
		
		return new KindleFileProcessor().getOutputPath(file);
		
	}

	private void genNCX() {

		String fileName = "voa.ncx";

		File file = new File(path + "/" + fileName);

		tmpFiles.add(file);

		try {

			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(file), "utf-8"));

			String begin = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n";
			begin += "<!DOCTYPE ncx PUBLIC \"-//NISO//DTD ncx 2005-1//EN\""
					+ "\n";
			begin += "	\"http://www.daisy.org/z3986/2005/ncx-2005-1.dtd\">"
					+ "\n";
			begin += "<ncx xmlns=\"http://www.daisy.org/z3986/2005/ncx/\" version=\"2005-1\" xml:lang=\"en-US\">"
					+ "\n";
			begin += "<head>" + "\n";
			begin += "<meta name=\"dtb:uid\" content=\"BookId\"/>" + "\n";
			begin += "<meta name=\"dtb:depth\" content=\"2\"/>" + "\n";
			begin += "<meta name=\"dtb:totalPageCount\" content=\"0\"/>" + "\n";
			begin += "<meta name=\"dtb:maxPageNumber\" content=\"0\"/>" + "\n";
			begin += "</head>" + "\n";
			begin += "<docTitle><text>VOA</text></docTitle>" + "\n";
			begin += "<docAuthor><text>www.jiyibao.com</text></docAuthor>"
					+ "\n";
			begin += "<navMap>" + "\n";

			String end = "</navMap>" + "\n" + "</ncx>";

			writer.write(begin);

			String name = "toc.html";
			String text = "Table of Contents";

			for (int i = 0; i < fileList.size() + 1; i++) {

				if (i != 0) {
					
					name = getConversionFileName((File) fileList.get(i - 1));

					text = name.substring(0, name.length() - 5);
				}

				String item = "<navPoint class=\"voa\" id=\"voa\" playOrder=\""
						+ i + "\">" + "\n";

				item += " <navLabel>" + "\n";

				item += "  <text>" + text + "</text>" + "\n";
				item += " </navLabel>" + "\n";
				item += " <content src=\"" + name + "\"/>" + "\n";
				item += "</navPoint>" + "\n";

				writer.write(item);
			}

			writer.write(end);

			writer.close();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private void genTOC() {

		String fileName = "toc.html";

		File file = new File(path + "/" + fileName);

		tmpFiles.add(file);

		try {

			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(file), "utf-8"));

			String begin = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">"
					+ "\n";
			begin += "<html xmlns=\"http://www.w3.org/1999/xhtml\">" + "\n";
			begin += "<head><title>Table of Contents</title></head>" + "\n";
			begin += "<body>" + "\n";
			begin += "<div>" + "\n";
			begin += " <h1><b>TABLE OF CONTENTS</b></h1>" + "\n";
			begin += "<br />" + "\n";
			begin += "<b>2011-09</b><br />" + "\n";
			begin += "<div><ul>" + "\n";

			String end = "</ul></div>" + "\n" + "</body>" + "\n" + "</html>";

			writer.write(begin);

			for (int i = 0; i < fileList.size(); i++) {
				
				
				String name = getConversionFileName((File) fileList.get(i));

				String item = "<li><a href=\"" + name + "\">"
						+ name.substring(0, name.length() - 5) + "</a></li>"
						+ "\n";

				writer.write(item);
			}

			writer.write(end);

			writer.close();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void genPublishFiles() {

		String outfileName = getType() + "VOA" + getDate();

		File opfFile = new File(path + "/" + outfileName + ".opf");
		File ncxFile = new File(path + "/" + "voa.ncx");
		File tocFile = new File(path + "/" + "toc.html");

		if (opfFile.exists()) {
			opfFile.delete();
		}

		if (ncxFile.exists()) {
			ncxFile.delete();
		}

		if (tocFile.exists()) {
			tocFile.delete();
		}

		genOPF();
		genNCX();
		genTOC();

		// copy css 文件

		URL url = this.getClass().getResource("/voa/voa.css");

		File file = new File(url.getFile());

		File dest = new File(path + "/" + file.getName());

		tmpFiles.add(dest);

		FileOperate.copyFile(url.getFile(), dest.getAbsolutePath());

		// 调用kindle API 生成 最终文件

		String kindlegen = "/home/gust/download/kindlegen_linux_2.6_i386_v1.2/./kindlegen";

		String cmd = kindlegen + " " + opfFile.getAbsolutePath();

		Util.executeCMD(cmd);

		// 最终文件拷贝到输出目录
		String outPath = "/home/gust/tmp/voa";

		String finalFileName = path + "/" + outfileName + ".mobi";

		tmpFiles.add(new File(finalFileName));

		FileOperate.copyFile(finalFileName, outPath + "/" + outfileName
				+ ".mobi");

	}
	

	public void clean() {

		// 删除所有临时文件
		for (int i = 0; i < tmpFiles.size(); i++) {
			
			File file = (File)tmpFiles.get(i);
			
			if (file.exists()){
				file.delete();
			}	
		}
		
		tmpFiles.clear();
	}

	static public Object drawDate(String name) {
		
		int i = name.indexOf("20");

		String year = name.substring(i, i + 4);
		String month = name.substring(i + 4, i + 6);
		String day = name.substring(i + 6, i + 8);
	
		return year + "." + month + "." + day;
	}
	
	static public void publishKindleFiles(String path){
		
		FileOperate.recursionDir(path, new KindleDirProcessor());
	}
	
	static public void paragraphLrcFiles(String path){
		
		FileOperate.recursionDir(path, new ParagraphDirProcessor());
	}
}
